/**
 * @Author: 罗显
 * @CreateTime: 2025-05-07
 * @Version: 1.0
 */


package com.it.material.service.impl;

import com.it.material.entity.NewsEntity;
import com.it.material.mapper.NewsMapper;
import com.it.material.service.NewsService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;

@Service
public class NewsServiceImpl implements NewsService {
    private static final Logger logger = LoggerFactory.getLogger(NewsServiceImpl.class);

    @Autowired
    private NewsMapper newsMapper;

    @Value("${file.upload.dir}") // 从 application.properties 中读取上传路径
    private String uploadPath;

    @Value("${file.upload.max-size}") // 从 application.properties 中读取上传文件大小限制
    private long maxFileSize;

    @Value("${file.upload.base-url}")  // 注入 baseUrl
    private String baseUrl;

    private static final List<String> ALLOWED_EXTENSIONS = Arrays.asList("jpg", "jpeg", "png", "gif"); //允许上传的图片类型
    private char[] newsId;

    public void publishNews(NewsEntity newsEntity, MultipartFile[] coverImages) throws IOException {

        // 1. 设置文章的基本信息
        newsEntity.setCreateTime(new Date());
        newsEntity.setUpdateTime(new Date());
        newsEntity.setPublishTime(null); // 发布时间为空
        // 2. 保存文章到数据库，获取文章ID
        newsMapper.insertNews(newsEntity);  // 插入后，newsEntity.getId() 就会有值

        Long newsId = newsEntity.getId();

        // 3. 上传图片，生成URL，并保存到数据库
        if (coverImages != null && coverImages.length > 0) {
            List<String> imageUrls = uploadImages(coverImages, newsId);
            newsMapper.insertNewsImages(newsId, imageUrls);
        }
    }

    private List<String> uploadImages(MultipartFile[] files, Long newsId) throws IOException {
        List<String> imageUrls = new ArrayList<>();

        // 确保上传目录存在
        Path uploadDir = createUploadDirectory(newsId);

        for (MultipartFile file : files) {
            if (file.isEmpty()) {
                logger.warn("文件为空，跳过上传");
                continue; // 跳过空文件
            }

            // 校验文件大小
            if (file.getSize() > maxFileSize) {
                logger.error("文件大小超过限制: {}", file.getOriginalFilename());
                throw new IOException("文件大小超过限制: " + maxFileSize + " bytes");
            }

            try {
                String imageUrl = uploadImage(file, uploadDir);
                imageUrls.add(imageUrl);
            } catch (IOException e) {
                logger.error("上传文件失败: {}", file.getOriginalFilename(), e);
                throw e; // 抛出异常，让Controller处理
            }
        }

        return imageUrls;
    }

    private Path createUploadDirectory(Long newsId) throws IOException {
        Path uploadDir = Paths.get(uploadPath, "news", String.valueOf(newsId));  // 按照文章ID创建子目录
        if (!Files.exists(uploadDir)) {
            try {
                Files.createDirectories(uploadDir);
                logger.info("创建上传目录: {}", uploadDir.toAbsolutePath());
            } catch (IOException e) {
                logger.error("创建上传目录失败: {}", uploadDir.toAbsolutePath(), e);
                throw e; // 抛出异常，让Controller处理
            }
        }
        return uploadDir;
    }

    private String uploadImage(MultipartFile file, Path uploadDir) throws IOException {
        String originalFilename = file.getOriginalFilename();
        String fileExtension = getFileExtension(originalFilename);

        // 校验文件类型
        if (!ALLOWED_EXTENSIONS.contains(fileExtension.toLowerCase())) {
            logger.error("文件类型不允许: {}", originalFilename);
            throw new IOException("文件类型不允许，只允许 " + ALLOWED_EXTENSIONS);
        }

        //校验是否是图片
        try {
            BufferedImage image = ImageIO.read(file.getInputStream());
            if (image == null) {
                throw new IOException("上传的文件不是有效的图像文件");
            }
        } catch (IOException e) {
            throw new IOException("上传的文件不是有效的图像文件: " + e.getMessage());
        }

        String uniqueFilename = UUID.randomUUID().toString() + "." + fileExtension; // 生成唯一文件名
        Path filePath = uploadDir.resolve(uniqueFilename);

        try {
            file.transferTo(filePath.toFile()); // 保存文件
            logger.info("文件上传成功: {}", filePath.toAbsolutePath());
        } catch (IOException e) {
            logger.error("保存文件失败: {}", filePath.toAbsolutePath(), e);
            throw e; // 抛出异常，让Controller处理
        }

        // 使用字符串连接符构建 URL
        String imageUrlPath = "news/" + String.valueOf(newsId) + "/" + uniqueFilename;
        String imageUrl = Paths.get(baseUrl, imageUrlPath).toString();

        return imageUrl;
    }

    private String getFileExtension(String filename) {
        if (filename == null || filename.isEmpty()) {
            return "";
        }
        int dotIndex = filename.lastIndexOf(".");
        if (dotIndex >= 0 && dotIndex < filename.length() - 1) { // Make sure the dot is not at the beginning or end
            return filename.substring(dotIndex + 1);
        }
        return "";
    }

}